home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / gnulib / dkbtrace / pbmplus / source / pnm / pnmflip.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-10  |  6.5 KB  |  247 lines

  1. /* pnmflip.c - perform one or more flip operations on a portable anymap
  2. **
  3. ** Copyright (C) 1989 by Jef Poskanzer.
  4. **
  5. ** Permission to use, copy, modify, and distribute this software and its
  6. ** documentation for any purpose and without fee is hereby granted, provided
  7. ** that the above copyright notice appear in all copies and that both that
  8. ** copyright notice and this permission notice appear in supporting
  9. ** documentation.  This software is provided "as is" without express or
  10. ** implied warranty.
  11. */
  12.  
  13. #include "pnm.h"
  14.  
  15. static void leftright ARGS(( int* aP, int* bP, int* cP, int* dP, int* eP, int* fP ));
  16. static void topbottom ARGS(( int* aP, int* bP, int* cP, int* dP, int* eP, int* fP ));
  17. static void transpose ARGS(( int* aP, int* bP, int* cP, int* dP, int* eP, int* fP ));
  18.  
  19. void
  20. main( argc, argv )
  21.     int argc;
  22.     char* argv[];
  23.     {
  24.     FILE* ifp;
  25.     int argn, cols, rows, format, newrows, newcols;
  26.     int a, b, c, d, e, f;
  27.     register int row, col, newrow, newcol;
  28.     xelval maxval;
  29.     void leftright(), topbottom(), transpose();
  30.     char* usage = "[-leftright|-lr] [-topbottom|-tb] [-transpose|-xy]\n            [-rotate90|-r90|-ccw] [-rotate270|r270|-cw]\n            [-rotate180|-r180] [pnmfile]";
  31.  
  32.     pnm_init( &argc, argv );
  33.  
  34.     argn = 1;
  35.  
  36.     /* Just check the validity of arguments here. */
  37.     while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
  38.     {
  39.     if ( pm_keymatch( argv[argn], "-lr", 2 ) ||
  40.          pm_keymatch( argv[argn], "-leftright", 2 ) )
  41.         { }
  42.     else if ( pm_keymatch( argv[argn], "-tb", 3 ) ||
  43.          pm_keymatch( argv[argn], "-topbottom", 3 ) )
  44.         { }
  45.     else if ( pm_keymatch( argv[argn], "-xy", 2 ) ||
  46.          pm_keymatch( argv[argn], "-transpose", 3 ) )
  47.         { }
  48.     else if ( pm_keymatch( argv[argn], "-r90", 3 ) ||
  49.          pm_keymatch( argv[argn], "-rotate90", 8 ) ||
  50.          pm_keymatch( argv[argn], "-ccw", 3 ) )
  51.         { }
  52.     else if ( pm_keymatch( argv[argn], "-r270", 3 ) ||
  53.          pm_keymatch( argv[argn], "-rotate270", 8 ) ||
  54.          pm_keymatch( argv[argn], "-cw", 3 ) )
  55.         { }
  56.     else if ( pm_keymatch( argv[argn], "-r180", 3 ) ||
  57.          pm_keymatch( argv[argn], "-rotate180", 8 ) )
  58.         { }
  59.     else
  60.         pm_usage( usage );
  61.     ++argn;
  62.     }
  63.  
  64.     if ( argn != argc )
  65.     {
  66.     ifp = pm_openr( argv[argn] );
  67.     ++argn;
  68.     }
  69.     else
  70.     ifp = stdin;
  71.  
  72.     if ( argn != argc )
  73.     pm_usage( usage );
  74.  
  75.     pnm_readpnminit( ifp, &cols, &rows, &maxval, &format );
  76.  
  77.     /* Now go through the flags again, this time accumulating transforms. */
  78.     a = 1; b = 0;
  79.     c = 0; d = 1;
  80.     e = 0; f = 0;
  81.     argn = 1;
  82.     while ( argn < argc && argv[argn][0] == '-' )
  83.     {
  84.     if ( pm_keymatch( argv[argn], "-lr", 2 ) ||
  85.          pm_keymatch( argv[argn], "-leftright", 2 ) )
  86.         leftright( &a, &b, &c, &d, &e, &f );
  87.     else if ( pm_keymatch( argv[argn], "-tb", 3 ) ||
  88.          pm_keymatch( argv[argn], "-topbottom", 3 ) )
  89.         topbottom( &a, &b, &c, &d, &e, &f );
  90.     else if ( pm_keymatch( argv[argn], "-xy", 2 ) ||
  91.          pm_keymatch( argv[argn], "-transpose", 3 ) )
  92.         transpose( &a, &b, &c, &d, &e, &f );
  93.     else if ( pm_keymatch( argv[argn], "-r90", 3 ) ||
  94.          pm_keymatch( argv[argn], "-rotate90", 8 ) ||
  95.          pm_keymatch( argv[argn], "-ccw", 3 ) )
  96.         {
  97.         transpose( &a, &b, &c, &d, &e, &f );
  98.         topbottom( &a, &b, &c, &d, &e, &f );
  99.         }
  100.     else if ( pm_keymatch( argv[argn], "-r270", 3 ) ||
  101.          pm_keymatch( argv[argn], "-rotate270", 8 ) ||
  102.          pm_keymatch( argv[argn], "-cw", 3 ) )
  103.         {
  104.         transpose( &a, &b, &c, &d, &e, &f );
  105.         leftright( &a, &b, &c, &d, &e, &f );
  106.         }
  107.     else if ( pm_keymatch( argv[argn], "-r180", 3 ) ||
  108.          pm_keymatch( argv[argn], "-rotate180", 8 ) )
  109.         {
  110.         leftright( &a, &b, &c, &d, &e, &f );
  111.         topbottom( &a, &b, &c, &d, &e, &f );
  112.         }
  113.     else
  114.         pm_error( "shouldn't happen!" );
  115.     ++argn;
  116.     }
  117.  
  118.     /* Okay, we've got a matrix. */
  119.     newcols = abs( a ) * cols + abs( c ) * rows;
  120.     newrows = abs( b ) * cols + abs( d ) * rows;
  121.  
  122.     if ( b == 0 && d == 1 && f == 0 )
  123.     {
  124.     /* In this case newrow is always equal to row, so we can do the
  125.     ** transform line by line and avoid in-memory buffering altogether.
  126.     */
  127.     register xel* xelrow;
  128.     register xel* newxelrow;
  129.     register xel* xP;
  130.  
  131.     xelrow = pnm_allocrow( cols );
  132.     newxelrow = pnm_allocrow( newcols );
  133.     pnm_writepnminit( stdout, newcols, newrows, maxval, format, 0 );
  134.  
  135.     for ( row = 0; row < rows; ++row )
  136.         {
  137.         pnm_readpnmrow( ifp, xelrow, cols, maxval, format );
  138.         for ( col = 0, xP = xelrow; col < cols; ++col, ++xP )
  139.         {
  140.         /* Transform a point:
  141.         **
  142.         **            [ a b 0 ]
  143.         **  [ x y 1 ] [ c d 0 ] = [ x2 y2 1 ]
  144.         **            [ e f 1 ]
  145.         */
  146.         newcol = a * col + c * row + e * ( newcols - 1 );
  147.         newxelrow[newcol] = *xP;
  148.         }
  149.         pnm_writepnmrow( stdout, newxelrow, newcols, maxval, format, 0 );
  150.         }
  151.     }
  152. #ifdef notdef
  153.     else if ( a == 0 && b != 0 && c != 0 && d == 0 )
  154.     {
  155.     /* This case is likely to thrash.  Can't think of any fix at the
  156.     ** moment, though.
  157.     */
  158.     }
  159. #endif /* notdef */
  160.     else
  161.     {
  162.     /* Generic case.  Read in the anymap a line at a time and transform
  163.     ** it into an in-memory array.
  164.     */
  165.     register xel* xelrow;
  166.     register xel** newxels;
  167.     register xel* xP;
  168.  
  169.     xelrow = pnm_allocrow( cols );
  170.     newxels = pnm_allocarray( newcols, newrows );
  171.  
  172.     for ( row = 0; row < rows; ++row )
  173.         {
  174.         pnm_readpnmrow( ifp, xelrow, cols, maxval, format );
  175.         for ( col = 0, xP = xelrow; col < cols; ++col, ++xP )
  176.         {
  177.         /* Transform a point:
  178.         **
  179.         **            [ a b 0 ]
  180.         **  [ x y 1 ] [ c d 0 ] = [ x2 y2 1 ]
  181.         **            [ e f 1 ]
  182.         */
  183.         newcol = a * col + c * row + e * ( newcols - 1 );
  184.         newrow = b * col + d * row + f * ( newrows - 1 );
  185.         newxels[newrow][newcol] = *xP;
  186.         }
  187.         }
  188.  
  189.     pnm_writepnm( stdout, newxels, newcols, newrows, maxval, format, 0 );
  190.     }
  191.  
  192.     pm_close( ifp );
  193.     pm_close( stdout );
  194.  
  195.     exit( 0 );
  196.     }
  197.  
  198. static void
  199. leftright( aP, bP, cP, dP, eP, fP )
  200.     int* aP;
  201.     int* bP;
  202.     int* cP;
  203.     int* dP;
  204.     int* eP;
  205.     int* fP;
  206.     {
  207.     *aP = - *aP;
  208.     *cP = - *cP;
  209.     *eP = - *eP + 1;
  210.     }
  211.  
  212. static void
  213. topbottom( aP, bP, cP, dP, eP, fP )
  214.     int* aP;
  215.     int* bP;
  216.     int* cP;
  217.     int* dP;
  218.     int* eP;
  219.     int* fP;
  220.     {
  221.     *bP = - *bP;
  222.     *dP = - *dP;
  223.     *fP = - *fP + 1;
  224.     }
  225.  
  226. static void
  227. transpose( aP, bP, cP, dP, eP, fP )
  228.     int* aP;
  229.     int* bP;
  230.     int* cP;
  231.     int* dP;
  232.     int* eP;
  233.     int* fP;
  234.     {
  235.     register int t;
  236.  
  237.     t = *aP;
  238.     *aP = *bP;
  239.     *bP = t;
  240.     t = *cP;
  241.     *cP = *dP;
  242.     *dP = t;
  243.     t = *eP;
  244.     *eP = *fP;
  245.     *fP = t;
  246.     }
  247.